package br.com.californiahotel.server.hibernate;

import java.util.Date;
import java.util.List;

import org.hibernate.SQLQuery;

import br.com.californiahotel.server.hibernate.models.Apartamento;
import br.com.californiahotel.server.hibernate.models.HibernateModel;

public class DatabaseUtils<T extends HibernateModel> {

	private final HibernateUtils hibernateUtils = new HibernateUtils();

	public void save(T model) {
		try {
			hibernateUtils.getSession().saveOrUpdate(model);
		} catch (RuntimeException re) {
			System.out.println(re.getCause());
			throw re;
		} finally {
			hibernateUtils.close();
		}
	}

	public void remove(T model) {
		try {
			hibernateUtils.getSession().delete(model);
		} catch (RuntimeException re) {
			System.out.println(re.getCause());
			throw re;
		} finally {
			hibernateUtils.close();
		}
	}

	public void removeById(Class<T> typeClass, Integer key) {
		remove(find(typeClass, key));
	}

	public void removeById(Class<T> typeClass, Long key) {
		try {
			T find = find(typeClass, key);
			hibernateUtils.getSession().delete(find);
		} catch (RuntimeException re) {
			System.out.println(re.getCause());
			throw re;
		} finally {
			hibernateUtils.close();
		}
	}

	public void removeById(Class<T> typeClass, String key) {
		try {
			T find = find(typeClass, key);
			hibernateUtils.getSession().delete(find);
		} catch (RuntimeException re) {
			System.out.println(re.getCause());
			throw re;
		} finally {
			hibernateUtils.close();
		}
	}

	@SuppressWarnings("unchecked")
	public T find(Class<T> typeClass, Integer id) {
		T hibernateModel = null;
		try {
			hibernateModel = (T) hibernateUtils.getSession().get(
					typeClass, id);
		} catch (RuntimeException re) {
			System.out.println(re.getCause());
			throw re;
		} finally {
			hibernateUtils.close();
		}
		return hibernateModel;
	}

	@SuppressWarnings("unchecked")
	public T find(Class<T> typeClass, Long id) {
		T hibernateModel = null;
		try {
			hibernateModel = (T) hibernateUtils.getSession().get(
					typeClass, id);
		} catch (RuntimeException re) {
			System.out.println(re.getCause());
			throw re;
		} finally {
			hibernateUtils.close();
		}
		return hibernateModel;
	}

	@SuppressWarnings("unchecked")
	public T find(Class<T> typeClass, String id) {
		T hibernateModel = null;
		try {
			hibernateModel = (T) hibernateUtils.getSession().get(
					typeClass, id);
		} catch (RuntimeException re) {
			System.out.println(re.getCause());
			throw re;
		} finally {
			hibernateUtils.close();
		}
		return hibernateModel;
	}

	@SuppressWarnings("unchecked")
	public List<T> findAll(Class<T> hibClass) {
		List<T> list = hibernateUtils.getSession().createCriteria(hibClass).list();
		hibernateUtils.close();
		return list;
	}

	@SuppressWarnings("unchecked")
	public List<T> executeQuery(Class<T> typeClass, String query, Object... objects) {
		SQLQuery sqlQuery = hibernateUtils.getSession().createSQLQuery(query);
		int i=0;
		for (Object object : objects) {
			sqlQuery.setParameter(i++, object);
		}
		sqlQuery.addEntity(typeClass);
		List<T> list = sqlQuery.list();
		hibernateUtils.close();
		return list;
	}

	public Object executeQueryUniqueResult(String query, Object... objects) {
		SQLQuery sqlQuery = hibernateUtils.getSession().createSQLQuery(query);
		int i=0;
		for (Object object : objects) {
			sqlQuery.setParameter(i++, object);
		}
		Object uniqueResult = sqlQuery.uniqueResult();
		hibernateUtils.close();
		return uniqueResult;
	}
	
	public List<Object> executeQuery(String query, Object... objects) {
		SQLQuery sqlQuery = hibernateUtils.getSession().createSQLQuery(query);
		int i=0;
		for (Object object : objects) {
			sqlQuery.setParameter(i++, object);
		}
		List<Object> list = sqlQuery.list();
		hibernateUtils.close();
		return list;
	}
}